/**
 * @file log.h
 * @author HaoyuWang (136046355@qq.com)
 * @brief spdlog简单封装
 * @version 0.1
 * @date 2025-02-11
 * 
 * @copyright Copyright (c) 2025
 * 
 */

#ifndef __LOG_H__
#define __LOG_H__


#include "spdlog/spdlog.h"
#include "spdlog/common.h"


#define LOGGER_INSTANCE() Log::GetInstance()
#define LOG_DEBUG(...)    LOGGER_INSTANCE().NativeLog(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, spdlog::level::debug, __VA_ARGS__)
#define LOG_INFO(...)     LOGGER_INSTANCE().NativeLog(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, spdlog::level::info, __VA_ARGS__)
#define LOG_WARN(...)     LOGGER_INSTANCE().NativeLog(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, spdlog::level::warn, __VA_ARGS__)
#define LOG_ERR(...)     LOGGER_INSTANCE().NativeLog(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, spdlog::level::err, __VA_ARGS__)


class Log
{
public:
    Log();
    ~Log();
    Log(const Log &) = delete;
    const Log operator=(const Log &) = delete;

    static Log& GetInstance();

    /**
     * @brief 初始化spdlog，TODO: 配置文件
     * 
     */
    void Init();
    void SetLevel(spdlog::level::level_enum level);

    /**
     * @brief 核心日志方法（供宏调用）
     * 
     * @tparam Args 
     * @param loc 
     * @param lvl 
     * @param fmt 
     * @param args 
     */
    template<typename... Args>
    void NativeLog(const spdlog::source_loc& loc, spdlog::level::level_enum lvl, 
                    fmt::format_string<Args...> fmt, Args&&... args) {
        logger_->log(loc, lvl, fmt, std::forward<Args>(args)...);
    }

public:
    std::shared_ptr<spdlog::logger> logger_;
    spdlog::level::level_enum level_;
};

#endif  // __LOG_H__